/*
 * ------------------------------------------------------------------
 * Copyright © 2017 Hangzhou DtDream Technology Co.,Lt d. All rights reserved.
 * ------------------------------------------------------------------
 *       Product:
 *   Module Name:
 *  Date Created: 2022/9/27
 *   Description:
 * ------------------------------------------------------------------
 * Modification History
 * DATE            Name           Description
 * ------------------------------------------------------------------
 * 2022/9/27    小谷 g2038          created
 * ------------------------------------------------------------------
 */
package com.gujh.java.jmx.client;


import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import java.io.Closeable;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

public class JmxClient implements Closeable {

    private final static ObjectMapper mapper = new ObjectMapper()
            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    private final JMXConnector jmxConnector;


    protected JmxClient(JMXServiceURL jmxServiceURL, Map<String, Object> environments) throws IOException {
        jmxServiceURL = Optional.ofNullable(jmxServiceURL).orElseThrow(RuntimeException::new);
        jmxConnector = JMXConnectorFactory.connect(jmxServiceURL, environments);
    }

    public <T> T invoke(ObjectName name, String operationName, List<Object> params,
                        List<String> paramTypes, Class<T> returnType)
            throws IOException, ReflectionException, InstanceNotFoundException, MBeanException {
        Object[] jmxParams = (null == params) ? new Object[0] : params.toArray();
        String[] jmxParamTypes = (null == paramTypes) ? new String[0] : paramTypes.toArray(new String[0]);
        MBeanServerConnection connection = jmxConnector.getMBeanServerConnection();
        Object response = connection.invoke(name, operationName, jmxParams, jmxParamTypes);
        if (Objects.isNull(response)) {
            return null;
        }
        return mapper.readValue(mapper.writeValueAsString(response), returnType);
    }

    public <T> T getAttributes(ObjectName name, String attribute, Class<T> returnType) {

        return null;
    }

    @Override
    public void close() throws IOException {
        if (Objects.nonNull(jmxConnector)) {
            jmxConnector.close();
        }
    }
}
